package com.wnxy.util;


import com.wnxy.annotation.Transactional;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
  基于CGLIB的动态代理工厂（事务管理器）
  目的 ： 产生动态代理对象
     步骤 ：
     1. 代理工厂implements通用的代理行为接口MethodInterceptor【方法拦截器】
     2. 将被代理对象作为成员变量引入
 */

public class TransactionManager implements MethodInterceptor {
    private Object target; //代理的目标对象
    public TransactionManager(Object target) {
        this.target = target;
    }

    // 产生一个基于CGLIB的动态代理对象（接口和类都可以产生代理）
    public Object createProxy(){
        //1.创建一个CGLIB的增强器
        Enhancer enhancer = new Enhancer();
        //2.设置代理对象的父类
        enhancer.setSuperclass(target.getClass());
        //3.设置代理的方法回调函数
        enhancer.setCallback(this);
        //4. 创建target代理对象
        Object proxy = enhancer.create();
        return proxy;
    }

    // 动态代理拦截target方法后需要执行的操作
    @Override
    public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = null;
        if(method.isAnnotationPresent(Transactional.class)){  // 判断方法上是否存在@Transactional注解（则添加事务）
            try{
                //1. 开启事务
                DBUtil.beginTransaction();
                //2. 执行原本的核心业务逻辑
                result = methodProxy.invokeSuper(obj, objects);
                //3. 提交事务
                DBUtil.commitTransaction();
            }catch (Exception e){
                //4. 数据回滚
                DBUtil.rollbackTransaction(e.getMessage());
            }finally {
                //5. 释放资源
                DBUtil.release();
            }
        }else{
            result = methodProxy.invokeSuper(obj, objects);
        }
        return result;
    }
}
